package com.ferry.config.client;

import com.ferry.config.client.enumValue.*;
import com.ferry.config.client.exception.FConfigException;
import com.ferry.config.client.invoker.ClientInvoker;
import com.ferry.config.client.invoker.HttpClientInvoker;
import com.ferry.config.client.listener.ConfigChangeListener;
import com.ferry.config.client.listener.GlobalConfigChangeListener;
import com.ferry.config.client.monitor.ConfigMonitor;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.Name;
import java.io.Closeable;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

/**
 * Created by daiyong
 */
public class FConfigClient implements Closeable {

	private static final Logger LOGGER = LoggerFactory.getLogger(FConfigClient.class);

	private String nameSpace;

	private String env;

	private static final String DEFAULT_NAMESPACE = "default";  //默认命名空间

	private ConfigMonitor configMonitor;

	private Multimap<String, ConfigChangeListener> configListeners = HashMultimap.create();

	private volatile GlobalConfigChangeListener globalConfigChangeListener = new GlobalConfigChangeListener() {
		@Override
		public void changed(Map<String, String> oldData, Map<String, String> newData) {
			//ignore
		}
	};

	/**
	 * 初始化client
	 */
	public void init() {
		try {
			ConfigMonitor configMonitor = new ConfigMonitor(this.nameSpace, this.env);
			this.configMonitor = configMonitor;
			this.configMonitor.init();

			LOGGER.error("FConfigClient success !");
		} catch (Exception e) {
			throw new FConfigException("FConfigClient fail", e);
		}
	}

	public void addListener(String key, ConfigChangeListener listener) {
		configMonitor.addListener(key, listener);
	}

	public void removeListener(String key, ConfigChangeListener listener) {
		configMonitor.removeListener(key, listener);
	}

	public String getValue(String key) {
		return configMonitor.getValue(key);
	}

	public Map<String, String> getAllKeyValues() {
		return configMonitor.getAllKeyValues();
	}

	public Set<String> getAllKeys() {
		return configMonitor.getAllKeys();
	}

	@Override
	public void close() throws IOException {
		configMonitor.destroy();
	}

	public void setGlobalConfigChangeListener(GlobalConfigChangeListener globalConfigChangeListener) {
		configMonitor.setGlobalConfigChangeListener(globalConfigChangeListener);
	}

	public void setNameSpace(String nameSpace) {
		this.nameSpace = nameSpace;
	}

	public void setEnv(String env) {
		this.env = env;
	}

	/**
	 * 单例模式
	 */
	private FConfigClient() {}

	public static class FClientHolder {
		private static FConfigClient instance = new FConfigClient();
	}

	public static FConfigClient newInstance() {
		return FClientHolder.instance;
	}

}
